<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>面向对象轮播图</title>
    <style>
        *{margin: 0;padding: 0;}
        ul, ol, li {
            list-style: none;
        }
        .banner {
            width: 600px;
            height: 400px;
            border: 10px solid #333;
            margin: 100px auto;
            position: relative;
            overflow: hidden;
        }
        .banner > ul {
            width: 500%;
            overflow: hidden;
            height: 100%;
            position: absolute;
            top: 0;
            left: 0;
        }
        .banner > ul > li {
            height: 100%;
            width: 600px;
            float: left;
            line-height: 400px;
            font-size: 100px;
            text-align: center;
            color: #fff;
        }
        .banner > ol {
            width: 175px;
            height: 25px;
            background-color: rgb(0, 0, 0, .5);
            border-radius: 15px;
            position: absolute;
            left: 50%;
            bottom: 30px;
            margin-left: -93px;
            padding-top: 5px;
            padding-right: 15px;
        }
        .banner > ol > li {
            width: 20px;
            height: 20px;
            background-color: #fff;
            border-radius: 50%;
            float: left;
            margin-left: 15px;
            cursor: pointer;
        }
        .banner > ol > li.active {
            background-color: orange;
        }
        .banner > div {
            width: 100%;
            height: 60px;
            position: absolute;
            left: 0;
            top: 50%;
            margin-top: -30px;
        }
        .banner > div > p {
            float: left;
            width: 40px;
            height: 100%;
            background-color: rgb(0, 0, 0, .5);
            line-height: 60px;
            text-align: center;
            font-size: 30px;
            color: #fff;
            cursor: pointer;
        }
        .banner > div > p:last-child {
            float: right;
        }
    </style>
</head>
<body>
    <div class="banner">
        <ul class="img_box">
            <li style="background-color: red;">1</li>
            <li style="background-color: skyblue;">2</li>
            <li style="background-color: violet;">3</li>
            <li style="background-color: black;">4</li>
            <li style="background-color: palegreen;">5</li>
        </ul>
        <ol>
            <!-- <li class="active"></li>
            <li></li>
            <li></li>
            <li></li>
            <li></li> -->
        </ol>
        <div>
            <p class="left"><</p>
            <p class="right">></p>
        </div>
    </div>

    <script src="./utils.js"></script>
    <script>
        class Banner {
            constructor (ele) {
                this.ele = document.querySelector(ele)
                // 获取元素
                this.imgBox = this.ele.querySelector('ul')
                this.pointBox = this.ele.querySelector('ol')
                // this.leftBtn = this.ele.querySelector('.left')
                // this.rightBtn = this.ele.querySelector('.right')

                // 准备变量
                this.timer = 0
                this.index = 1
                this.flag = true
                this.banner_width = this.ele.clientWidth

                this.init() // 调用启动器
            }

            // 1. 准备个启动器
            init () {
                this.setPoint()
                this.copyEle()
                this.autoPlay()
                this.overOut()
                this.bindEvent()
                this.changeTab()
            }

            // 设置焦点
            setPoint() {
                const num = this.imgBox.children.length
                const frg = document.createDocumentFragment()

                for (let i = 0; i < num; i++) {
                    const li = document.createElement('li')
                    li.dataset.id = i + 1
                    li.classList.add('point')
                    if (i === 0) li.classList.add('active')
                    frg.appendChild(li)
                }
                this.pointBox.appendChild(frg)

                this.pointBox.style.width = num * 35 + 'px'
                this.pointBox.style.marginLeft = -this.pointBox.offsetWidth / 2
            }   

            // 复制元素
            copyEle() {
                const first = this.imgBox.firstElementChild.cloneNode(true)
                const last = this.imgBox.lastElementChild.cloneNode(true)

                this.imgBox.appendChild(first)
                this.imgBox.insertBefore(last, this.imgBox.firstElementChild)

                // 从新设置宽度
                this.imgBox.style.width = this.imgBox.children.length * 100 + '%'
                this.imgBox.style.left = -this.index * this.banner_width + 'px'
            }

            // 自动轮播
            autoPlay() {
                this.timer = setInterval(() => {
                    this.index++
                    move(this.imgBox, { left: -this.index * this.banner_width }, this.moveEnd.bind(this))
                }, 2000)
            }

            // 运动结束
            moveEnd() {
                // console.log(this)
                if (this.index >= this.imgBox.children.length - 1) {
                    this.index = 1
                    this.imgBox.style.left = -this.index * this.banner_width + 'px'
                }
                if (this.index <= 0) {
                    this.index = this.imgBox.children.length - 2
                    this.imgBox.style.left = -this.index * this.banner_width + 'px'
                }
                // for (let i = 0; i < this.pointBox.children.length; i++) {
                //     this.pointBox.children[i].classList.remove('active')
                // }
                // 想用 forEach, 但是没有
                // 1. 转成数组
                // ;[...this.pointBox.children].forEach(item => item.classList.remove('active'))
                // 2. 借用数组方法
                ;[].forEach.call(this.pointBox.children, item => item.classList.remove('active'))

                this.pointBox.children[this.index - 1].classList.add('active')

                this.flag = true
            }
            
            // 移入移出
            overOut() {
                this.ele.addEventListener('mouseover', () => clearInterval(this.timer))
                this.ele.addEventListener('mouseout', () => this.autoPlay())
            }

            // 点击事件
            bindEvent() {
                this.ele.addEventListener('click', e => {
                    e = e || window.event
                    const target = e.target || e.srcElement
                    if (target.className === 'left') {
                        if (!this.flag) return
                        this.flag = false
                        this.index--
                        move(this.imgBox, { left: -this.index * this.banner_width }, this.moveEnd.bind(this))
                    }
                    if (target.className === 'right') {
                        if (!this.flag) return
                        this.flag = false
                        this.index++
                        move(this.imgBox, { left: -this.index * this.banner_width }, this.moveEnd.bind(this))
                    }
                    if (target.className === 'point') {
                        if (!this.flag) return
                        this.flag = false
                        const index = target.dataset.id - 0
                        this.index = index
                        move(this.imgBox, { left: -this.index * this.banner_width }, this.moveEnd.bind(this))
                    }
                })
            }
            
            // 切换标签页
            changeTab() {
                document.addEventListener('visibilitychange', () => {
                    if(document.visibilityState === 'hidden') clearInterval(this.timer)
                    else this.autoPlay()
                })
            }
        }
        
        new Banner('.banner')
    </script>
</body>
</html>